package bev.article;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;

import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;

import bev.ConnectionManager;
import bev.HelperUtility;

/**
 * Used to store and work with article data about an object in memory.
 */
public class ObjectArticle extends BaseArticle {
    // Object article data.
    String description, location, objecttype;
    boolean instance;

    // Text fields for editing.
    JTextField txtDescription;
    JComboBox<String> cmbInstance;
    JTextArea txtLocation;
    JTextArea txtObjectType;

    /**
     * Instantiates a new <i>object</i> article.
     */
    public ObjectArticle() {
        super();

        // Default values.
        description = "";
        instance = false;
        location = "";
        objecttype = "";
    }

    @Override
    public void loadArticle( int id ) {
        id_num = id;

        // Get the results set containing the object.
        try {
            ResultSet rs = ConnectionManager
                    .RunSQLQuery( String
                            .format(
                                    "SELECT id, name, description, created, updated, instance, location, objecttype FROM objects WHERE id = %d",
                                    id ) );

            if ( rs.next() ) {
                int object_id = rs.getInt( "id" );
                if ( object_id != id ) {
                    System.err.print( "ID from database did not match." );
                    return;
                }

                // Common data.
                name = HelperUtility.stringOrDefault( rs.getString( "name" ) );
                timeCreated = rs.getTimestamp( "created" );
                timeModified = rs.getTimestamp( "updated" );

                // Object data.
                description = HelperUtility.stringOrDefault( rs
                        .getString( "description" ) );
                instance = rs.getBoolean( "instance" );
                location = HelperUtility.stringOrDefault( rs
                        .getString( "location" ) );
                objecttype = HelperUtility.stringOrDefault( rs
                        .getString( "objecttype" ) );
            }

            ConnectionManager.closeConnection();
        } catch ( SQLException ex ) {
            ex.printStackTrace();
        } catch ( ClassNotFoundException ex ) {
            ex.printStackTrace();
        }
    }

    @Override
    public void storeArticle() {
        try {
            // Get all the object article IDs from the database.
            ResultSet rs = ConnectionManager
                    .RunSQLQuery( "SELECT id FROM objects" );

            // Check if this article's ID exists in database.
            boolean exists = false;
            while ( rs.next() ) {
                int person_id = rs.getInt( "id" );
                if ( person_id == id_num ) {
                    exists = true;
                    break;
                }
            }

            // Update article in database if it exists.
            if ( exists ) {
                int instanceint = ( instance ? 1 : 0 );
                String query = String
                        .format(
                                //                  name,      desc,       inst,       loc,       type
                                "UPDATE objects SET %s = '%s', %s = '%s' , %s = '%d' , %s = '%s', %s = '%s'  WHERE id = %d",
                                "name", ConnectionManager.processEscapeChars( name ),
                                "description", ConnectionManager.processEscapeChars( description ),
                                "instance", instanceint,
                                "location", ConnectionManager.processEscapeChars( location ),
                                "objecttype", ConnectionManager.processEscapeChars( objecttype ),
                                id_num );

                System.out.printf( "Insert query: '%s'\n", query );
                ConnectionManager.RunSQLUpdateQuery( query );
            }
            // Else insert as a new article.
            else {
                int instanceint = ( instance ? 1 : 0 );
                String query = String
                        .format(
                                "INSERT INTO objects (name, description, created, instance, location, objecttype) VALUES ('%s', '%s', '%s', '%d', '%s', '%s')",
                                ConnectionManager.processEscapeChars( name ),
                                ConnectionManager.processEscapeChars( description ),
                                HelperUtility.formatDatabaseTimeStamp( timeCreated ),
                                instanceint, ConnectionManager.processEscapeChars( location ),
                                ConnectionManager.processEscapeChars( objecttype ) );

                System.out.printf( "Insert query: '%s'\n", query );
                ConnectionManager.RunSQLUpdateQuery( query );
            }

            ConnectionManager.closeConnection();
        } catch ( SQLException ex ) {
            ex.printStackTrace();
        } catch ( ClassNotFoundException ex ) {
            ex.printStackTrace();
        }
    }

    @Override
    protected void addBodyText( JTextPane textPane ) {
        // Description.
        if ( description.length() > 0 ) {
            ArticleFormatter.addSmallHeader( textPane, "Description" );
            ArticleFormatter.addNewLine( textPane, 1 );
            ArticleFormatter.addRegular( textPane, description );
            ArticleFormatter.addNewLine( textPane, 2 );
        }

        // Instance.
        ArticleFormatter.addSmallHeader( textPane, "Instance: " );
        if ( instance == false ) {
            ArticleFormatter.addRegular( textPane, "General Item" );
        } else {
            ArticleFormatter.addRegular( textPane, "Specific Item" );
        }
        ArticleFormatter.addNewLine( textPane, 2 );

        // Location.
        if ( location.length() > 0 ) {
            ArticleFormatter.addSmallHeader( textPane, "Location" );
            ArticleFormatter.addNewLine( textPane, 1 );
            ArticleFormatter.addRegular( textPane, location );
            ArticleFormatter.addNewLine( textPane, 2 );
        }

        // Object Type.
        if ( objecttype.length() > 0 ) {
            ArticleFormatter.addSmallHeader( textPane, "Object Type" );
            ArticleFormatter.addNewLine( textPane, 1 );
            ArticleFormatter.addRegular( textPane, objecttype );
            ArticleFormatter.addNewLine( textPane, 1 );
        }
    }

    @Override
    protected JPanel getBodyEditControls() {
        ArticleEditPanel panel = new ArticleEditPanel();

        // Description.
        txtDescription = new JTextField( description );

        // Instance combo box.
        Vector<String> instances = new Vector<String>();
        instances.add( "General Item" );
        instances.add( "Specific Item" );
        cmbInstance = new JComboBox<String>( instances );
        if ( instance == false ) {
            cmbInstance.setSelectedItem( "General Item" );
        } else {
            cmbInstance.setSelectedItem( "Specific Item" );
        }

        // Location.
        txtLocation = new JTextArea( location );
        txtLocation.setLineWrap( true );
        JScrollPane spLocation = new JScrollPane( txtLocation );
        spLocation
                .setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED );

        // Object Type.
        txtObjectType = new JTextArea( objecttype );
        txtObjectType.setLineWrap( true );
        JScrollPane spObjectType = new JScrollPane( txtObjectType );
        spObjectType
                .setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED );

        // Add the fields to the article edit view.
        panel.addComponent( "Description", txtDescription,
                ArticleEditPanel.getLargeFieldSize() );
        panel.addComponent( "Instance", cmbInstance,
                ArticleEditPanel.getSmallFieldSize() );
        panel.commitComponents();

        panel.addComponent( "Location", spLocation );
        panel.addComponent( "Object Type", spObjectType );
        panel.commitComponents();

        return panel;
    }

    @Override
    protected void saveCustomEditData() {
        description = HelperUtility.getTextNullCheck( txtDescription );
        if ( cmbInstance.getSelectedItem() == "General Item" ) {
            instance = false;
        } else {
            instance = true;
        }
        location = HelperUtility.getTextNullCheck( txtLocation );
        objecttype = HelperUtility.getTextNullCheck( txtObjectType );
    }

    @Override
    protected boolean validateBodyEditFields() {
        // None for Object articles.

        return true;
    }
}
